package com.soccerlover9527.jadis.util;

/**
 * <p></p>
 *
 * @author soccerlover9527@gmail.com
 * @since 2023-08-09
 */
public class BitUtil {
    /**
     * get a bit value from byte
     *
     * @param b      byte value
     * @param offset bit offset
     * @return 0, 1
     * @throws IndexOutOfBoundsException if offset bigger than 7 or less than 0
     */
    public static byte getBit(byte b, int offset) {
        checkOffsetInByte(offset);
        return (byte) (b >> offset & 0x1);
    }

    /**
     * Sets the specified offset from bit to byte
     *
     * @param value  byte value
     * @param bit    bit value
     * @param offset bit offset
     * @return new byte value
     */
    public static byte setBit(byte value, byte bit, int offset) {
        checkOffsetInByte(offset);

        if (bit == 0) {
            return (byte) (value & ~(1 << offset));
        }
        return (byte) (value | (1 << offset));
    }

    /**
     * check bit offset range in one byte
     *
     * @param offset bit offset
     */
    private static void checkOffsetInByte(int offset) {
        if (offset > 7 || offset < 0) {
            throw new IndexOutOfBoundsException("bit offset can't bigger than 7 or less than 0");
        }
    }

    /**
     * Verifies whether the input value is a bit
     *
     * @param b input value
     */
    public static void checkBitValue(byte b) {
        if (b != 0 && b != 1) {
            throw new IllegalArgumentException("bit value only accept 0,1");
        }
    }
}
